package com.own.demo.jts;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.own.demo.utils.CommWriterFileInfo;
import com.own.demo.utils.DateUtils;
import com.own.demo.utils.FileToStringUtils;
import com.own.demo.utils.geo.PoiTypeEnums;
import com.own.demo.utils.geo.buffer.LineBufferImpl;
import com.own.demo.vo.Bounds;
import com.own.demo.vo.NodeOsmInfo;
import org.locationtech.jts.geom.LineString;

import java.io.BufferedWriter;
import java.io.File;
import java.text.ParseException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;

public class 生成osm {
//    private  static BufferedWriter bufferedWriter =null;
    private static AtomicLong indexNum = new AtomicLong(1);
    private static Map<String, NodeOsmInfo> lonLatMap = new ConcurrentHashMap<>(100000);

    public static LineBufferImpl defaultBuffer = (LineBufferImpl) PoiTypeEnums.POLYLINE.getBufferUtil();
    private static String url="F:\\airMatch\\200米-40-60.osm";

    public static void main(String[] args) throws ParseException {
        BufferedWriter   bufferedWriter = CommWriterFileInfo.getWriterBuffer(url, false);
        //head
        writerHeader(bufferedWriter);
        //边界
        Bounds boundingBox = new Bounds(114.260085, 114.260085, 27.848061, 28.661844);
        setBounds(boundingBox,bufferedWriter);
        try{
            File geoZJ = new File("F:\\airMatch\\200米-40-60.geojson");
            String geoData = FileToStringUtils.txt2String(geoZJ);
            JSONObject jsonObject=JSONObject.parseObject(geoData);
            geoData="";

            JSONObject buildData=  buildInstall();

            JSONArray jsonArray= buildData.getJSONArray("features");
            jsonObject.getJSONArray("features").addAll(jsonArray);
            getJsonNode(jsonObject);

            writerNode(bufferedWriter);
            writerWay(jsonObject,bufferedWriter);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            endString(bufferedWriter);
        }

    }

    public static void writeOsm(String url,JSONObject jsonObject,Bounds boundingBox){
        indexNum = new AtomicLong(1);
        lonLatMap = new ConcurrentHashMap<>(100000);
        System.out.println(url);
        System.out.println(jsonObject.toJSONString());
        System.out.println();
        BufferedWriter bufferedWriter = CommWriterFileInfo.getWriterBuffer(url, false);
        writerHeader(bufferedWriter);
        setBounds(boundingBox,bufferedWriter);
        getJsonNode(jsonObject);
        writerNode(bufferedWriter);
        writerWay(jsonObject,bufferedWriter);
        endString(bufferedWriter);
    }

    private static JSONObject buildInstall(){
        File geoZJ = new File("E:\\ownCode\\emg-geojson\\src\\test\\java\\com\\own\\demo\\jts\\building6.geojson");
        JSONObject geoData = JSONObject.parseObject(FileToStringUtils.txt2String(geoZJ));
        JSONArray jsonArray = geoData.getJSONArray("features");

        JSONArray jsonArrayReturn=new JSONArray(1000);
        int row=jsonArray.size();
        for (int i = 0; i < row; i++) {
            JSONObject jsonObject = jsonArray.getJSONObject(i);
            JSONObject geometry = jsonObject.getJSONObject("geometry");
            JSONObject properties = jsonObject.getJSONObject("properties");
            Integer floor= properties.getInteger("Floor");
            if(floor<14){
                continue;
            }
            JSONArray coordinates = geometry.getJSONArray("coordinates").getJSONArray(0);
            geometry.put("coordinates",coordinates);
            jsonArrayReturn.add(jsonObject);
        }
        geoData.put("features",jsonArrayReturn);
        System.out.println(jsonArrayReturn.size());
        return geoData;
    }

    public static void writerWay(JSONObject jsonObject,BufferedWriter bufferedWriter){
        JSONArray jsonArray = jsonObject.getJSONArray("features");
        int row = jsonArray.size();
        for (int i = 0; i < row; i++) {
            StringBuilder sb=new StringBuilder(1024);
            String id=indexNum.getAndIncrement()+"";
            sb.append("   <way id=\""+id+"\" visible=\"true\" version=\"1\"> \r\n");

            JSONObject indexJsonObje = jsonArray.getJSONObject(i);
            JSONObject geometry = indexJsonObje.getJSONObject("geometry");
            JSONArray lonlatList = geometry.getJSONArray("coordinates");
            JSONObject properties=jsonObject.getJSONObject("properties");

            int index=lonlatList.size();
            for (int j = 0; j < index; j++) {
                JSONArray point = lonlatList.getJSONArray(j);
                double lon = point.getDouble(0);
                double lat = point.getDouble(1);
                String key = lon + "+" + lat;
                NodeOsmInfo nodeInfo=lonLatMap.get(key);
                sb.append("      <nd ref=\""+nodeInfo.getIndex()+"\"/> \r\n");
            }

            if(properties !=null) {
                Set<String> keys = properties.keySet();
                Iterator<String> iterator = keys.iterator();
                while(iterator.hasNext()){
                    String key = iterator.next();
                    if(!"name".equals(key)) {
                        String o = properties.getString(key);
                        String tags = "      <tag k=\"" + key + "\" v=\"" + o + "\"/> \r\n";
                        sb.append(tags);
                    }
                }
            }

            String key="name";
            String value=id+"-"+i;
            String tags="      <tag k=\""+key+"\" v=\""+value+"\"/> \r\n";
            sb.append(tags);

            sb.append("      <tag k=\"highway\" v=\"motorway\"/> \r\n");
            sb.append("   </way> \r\n");
            String wayStr=sb.toString();
            CommWriterFileInfo.writer(bufferedWriter, wayStr);
            System.out.println("Way: "+ DateUtils.getDateYYSs(new Date())+" "+wayStr);
        }
    }

    public static void writerWayTemp(JSONObject jsonObject,BufferedWriter bufferedWriter){
        JSONArray jsonArray = jsonObject.getJSONArray("features");
        int row = jsonArray.size();
        for (int i = 0; i < row; i++) {
            StringBuilder sb=new StringBuilder(1024);
            String id=indexNum.getAndIncrement()+"";
            sb.append("   <way id=\""+id+"\" visible=\"true\" version=\"1\"> \r\n");

            JSONObject indexJsonObje = jsonArray.getJSONObject(i);
            JSONObject geometry = indexJsonObje.getJSONObject("geometry");
            JSONArray lonlatList = geometry.getJSONArray("coordinates");
            JSONObject properties=jsonObject.getJSONObject("properties");

            int index=lonlatList.size();
            for (int j = 0; j < index; j++) {
                JSONArray point = lonlatList.getJSONArray(j);
                double lon = point.getDouble(0);
                double lat = point.getDouble(1);
                String key = lon + "+" + lat;
                NodeOsmInfo nodeInfo=lonLatMap.get(key);
                sb.append("      <nd ref=\""+nodeInfo.getIndex()+"\"/> \r\n");
            }

            if(properties !=null) {
                Set<String> keys = properties.keySet();
                Iterator<String> iterator = keys.iterator();
                while(iterator.hasNext()){
                    String key = iterator.next();
                    if(!"name".equals(key)) {
                        String o = properties.getString(key);
                        String tags = "      <tag k=\"" + key + "\" v=\"" + o + "\"/> \r\n";
                        sb.append(tags);
                    }
                }
            }

            String key="name";
            String value=id+"-"+i;
            String tags="      <tag k=\""+key+"\" v=\""+value+"\"/> \r\n";
            sb.append(tags);

            sb.append("      <tag k=\"highway\" v=\"motorway\"/> \r\n");
            sb.append("   </way> \r\n");
            String wayStr=sb.toString();
            CommWriterFileInfo.writer(bufferedWriter, wayStr);
            System.out.println("Way: "+ DateUtils.getDateYYSs(new Date())+" "+wayStr);
        }
    }

    public static void getJsonNode(JSONObject geoJson) {
        JSONArray jsonArray = geoJson.getJSONArray("features");
        int row = jsonArray.size();
        for (int i = 0; i < row; i++) {
            JSONObject jsonObject = jsonArray.getJSONObject(i);
            JSONObject properties = jsonObject.getJSONObject("properties");
            JSONObject geometry = jsonObject.getJSONObject("geometry");
            JSONArray lonlatList = geometry.getJSONArray("coordinates");
            coordinates(lonlatList,properties);
        }
    }

    private static void coordinates(JSONArray lonlatList,JSONObject properties){
        int lonlatSize = lonlatList.size();
        for (int j = 0; j < lonlatSize; j++) {
            JSONArray point = lonlatList.getJSONArray(j);
            double lon = point.getDouble(0);
            double lat = point.getDouble(1);
            String key = lon + "+" + lat;
            String index=indexNum.getAndIncrement()+"";
            String propKey = "name";
            System.out.println("写入node: "+ DateUtils.getDateYYSs(new Date())+" key:"+index+"  xy:"+key);
            lonLatMap.put(key, new NodeOsmInfo(properties.getString(propKey), index, propKey, lon, lat));
        }
    }


    public static void writerNode(BufferedWriter bufferedWriter) {
        for (Map.Entry<String, NodeOsmInfo> node : lonLatMap.entrySet()) {
            NodeOsmInfo nodeInfo=node.getValue();
            double lon=nodeInfo.getX();
            double lat=nodeInfo.getY();
            String nodeStr="<node id=\""+nodeInfo.getIndex()+"\" visible=\"true\" version=\"1\" lat=\""+lat+"\" lon=\""+lon+"\"/>";
            CommWriterFileInfo.writer(bufferedWriter, nodeStr);
            System.out.println("写入node: "+nodeStr);
        }
    }



    private static void setBounds(Bounds boundingBox,BufferedWriter bufferedWriter){
        double minLat=boundingBox.getMinLat();
        double maxLat=boundingBox.getMaxLat();
        double minLon=boundingBox.getMinLon();
        double maxLong=boundingBox.getMaxLon();
        long index=indexNum.getAndIncrement();
        String bounds="<bounds minlat=\""+minLat+"\" minlon=\""+minLon+"\" maxlat=\""+maxLat+"\" maxlon=\""+maxLong+"\" id=\"1\" version=\""+index+"\"/>";
        CommWriterFileInfo.writer(bufferedWriter, bounds);
    }
    private static void writerHeader(BufferedWriter bufferedWriter){
        String head="<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
                "<osm version=\"0.6\" generator=\"CGImap 0.8.8 (587855 spike-08.openstreetmap.org)\" copyright=\"OpenStreetMap and contributors\" attribution=\"http://www.openstreetmap.org/copyright\" license=\"http://opendatacommons.org/licenses/odbl/1-0/\">";
        CommWriterFileInfo.writer(bufferedWriter, head);
    }

    private static void endString(BufferedWriter bufferedWriter){
        CommWriterFileInfo.writer(bufferedWriter, "</osm>");
    }
}
